<template>
  <el-dialog
    v-model="visible"
    title="编辑实验配置"
    width="1200px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    class="config-editor-dialog"
    custom-class="config-editor-dialog-wrapper"
  >
    <!-- 工具栏提示 -->
    <div class="dialog-toolbar">
      <el-alert type="info" :closable="false" show-icon>
        <template #title>
          <span style="font-size: 13px;">
            您正在编辑节点「{{ nodeName }}」的实验配置，支持在字段中插入变量引用（如 {{ exampleVariable }}）
          </span>
        </template>
      </el-alert>
    </div>

    <!-- 标签页：表单视图 / YAML 视图 -->
    <el-tabs v-model="activeTab" class="config-tabs" @tab-change="handleTabChange">
      <!-- 表单视图 -->
      <el-tab-pane label="表单视图" name="form">
        <template #label>
          <span class="tab-label">
            <el-icon><Document /></el-icon>
            表单视图
          </span>
        </template>
        <div class="tab-content">
          <TemplateFormRenderer
            ref="formRendererRef"
            v-model="formData"
            :fields-config="TEMPLATE_FIELDS_CONFIG"
            :readonly="false"
            :enable-variable-insertion="true"
            @change="handleFormChange"
            @insert-variable="handleInsertVariable"
          />
        </div>
      </el-tab-pane>

      <!-- YAML 视图 -->
      <el-tab-pane label="YAML 视图" name="yaml">
        <template #label>
          <span class="tab-label">
            <el-icon><Notebook /></el-icon>
            YAML 视图
          </span>
        </template>
        <div class="tab-content yaml-view">
          <div class="yaml-toolbar">
            <el-button
              size="small"
              @click="showYamlVariableSelector"
              :icon="Link"
            >
              插入变量
            </el-button>
          </div>
          <YamlEditor
            ref="yamlEditorRef"
            v-model="yamlContent"
            :readonly="false"
            @change="handleYamlChange"
          />
        </div>
      </el-tab-pane>
    </el-tabs>

    <!-- 底部操作按钮 -->
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :loading="saving">
          <el-icon><Check /></el-icon>
          确认保存
        </el-button>
      </div>
    </template>

    <!-- 变量选择器 -->
    <VariableSelector
      v-model="variableSelectorVisible"
      :predecessor-nodes="predecessorNodes"
      @confirm="handleVariableSelected"
    />
  </el-dialog>
</template>

<script setup>
import { ref, watch, computed, nextTick } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Document, Notebook, Link, Check } from '@element-plus/icons-vue'
import TemplateFormRenderer from '@/components/TemplateFormRenderer/index.vue'
import YamlEditor from '@/components/YamlEditor/index.vue'
import VariableSelector from '@/components/VariableSelector/index.vue'
import { TEMPLATE_FIELDS_CONFIG } from '@/config/templateFieldsConfig'
import {
  parseYaml,
  stringifyYaml,
  extractFormData,
  buildYamlFromForm,
  validateFormData,
  deepClone,
  isEqual
} from '@/utils/yamlTemplateParser'
import { useTemplateStore } from '@/stores/template'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  nodeConfig: {
    type: Object,
    required: true
  },
  nodeName: {
    type: String,
    default: '未命名节点'
  },
  predecessorNodes: {
    type: Array,
    default: () => []
  }
})

const emit = defineEmits(['update:modelValue', 'confirm'])

const templateStore = useTemplateStore()

// 示例变量文本（用于提示信息）
const exampleVariable = '{{nodeA.output}}'

// 状态管理
const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

const activeTab = ref('form')
const formData = ref({})
const yamlContent = ref('')
const originalYamlData = ref({})
const currentFieldPath = ref('')
const variableSelectorVisible = ref(false)
const saving = ref(false)
const yamlEditorRef = ref(null)
const formRendererRef = ref(null)

// 同步标志（防止循环更新）
let isSyncing = false

// 快照（用于检测实际变化）
const lastSyncSnapshot = ref({
  form: {},
  yaml: ''
})

// 初始化：从模板或已保存配置加载
watch(() => props.modelValue, async (newVal) => {
  if (newVal) {
    await loadConfig()
  }
})

// 加载配置
const loadConfig = async () => {
  try {
    let yamlString = ''

    // 优先从已保存的配置加载
    if (props.nodeConfig.experimentConfig) {
      yamlString = props.nodeConfig.experimentConfig
      console.log('从已保存配置加载:', yamlString.substring(0, 100))
    }
    // 否则从模板加载
    else if (props.nodeConfig.template_id) {
      const template = await templateStore.getTemplateById(props.nodeConfig.template_id)
      if (template) {
        yamlString = template.yaml_content
        console.log('从模板加载:', template.name)
      } else {
        ElMessage.error('加载模板失败')
        return
      }
    } else {
      ElMessage.warning('请先选择实验模板')
      visible.value = false
      return
    }

    // 解析 YAML 并提取表单数据
    const yamlData = parseYaml(yamlString)
    originalYamlData.value = deepClone(yamlData)
    yamlContent.value = yamlString
    formData.value = extractFormData(yamlData, TEMPLATE_FIELDS_CONFIG)

    // 初始化快照
    lastSyncSnapshot.value.form = deepClone(formData.value)
    lastSyncSnapshot.value.yaml = yamlString

    console.log('配置加载完成')
  } catch (error) {
    console.error('加载配置失败:', error)
    ElMessage.error('配置加载失败: ' + error.message)
  }
}

// 表单数据变化 -> 同步到 YAML
const handleFormChange = (newFormData) => {
  if (isSyncing) return
  if (activeTab.value !== 'form') return

  // 检查是否真的变化了
  if (isEqual(newFormData, lastSyncSnapshot.value.form)) {
    return
  }

  isSyncing = true

  try {
    // 从表单数据构建完整 YAML 对象
    const newYamlData = buildYamlFromForm(
      newFormData,
      originalYamlData.value,
      TEMPLATE_FIELDS_CONFIG
    )

    // 转换为 YAML 字符串
    const newYamlContent = stringifyYaml(newYamlData)

    // 更新 YAML 内容
    yamlContent.value = newYamlContent
    originalYamlData.value = deepClone(newYamlData)

    // 更新快照
    lastSyncSnapshot.value.form = deepClone(newFormData)
    lastSyncSnapshot.value.yaml = newYamlContent

    console.log('表单 → YAML 同步完成')
  } catch (error) {
    console.error('同步到 YAML 失败:', error)
  } finally {
    isSyncing = false
  }
}

// YAML 内容变化 -> 同步到表单
const handleYamlChange = (newYamlContent) => {
  if (isSyncing) return
  if (activeTab.value !== 'yaml') return

  // 类型检查
  if (typeof newYamlContent !== 'string') {
    console.error('handleYamlChange: 期望字符串类型，实际类型:', typeof newYamlContent)
    return
  }

  // 检查是否真的变化了
  if (newYamlContent === lastSyncSnapshot.value.yaml) {
    return
  }

  isSyncing = true

  try {
    // 解析 YAML
    const newYamlData = parseYaml(newYamlContent)

    // 提取表单数据
    const newFormData = extractFormData(newYamlData, TEMPLATE_FIELDS_CONFIG)

    // 更新表单数据
    formData.value = newFormData
    originalYamlData.value = deepClone(newYamlData)

    // 更新快照
    lastSyncSnapshot.value.form = deepClone(newFormData)
    lastSyncSnapshot.value.yaml = newYamlContent

    console.log('YAML → 表单 同步完成')
  } catch (error) {
    console.error('YAML 解析失败:', error)
    ElMessage.error('YAML 格式错误，请检查语法')
  } finally {
    isSyncing = false
  }
}

// 标签页切换
const handleTabChange = (tabName) => {
  console.log('切换到标签页:', tabName)
}

// 处理变量插入（表单视图）
const handleInsertVariable = (fieldPath) => {
  currentFieldPath.value = fieldPath
  variableSelectorVisible.value = true
}

// 处理变量插入（YAML 视图）
const showYamlVariableSelector = () => {
  currentFieldPath.value = '__yaml__'
  variableSelectorVisible.value = true
}

// 变量选择完成
const handleVariableSelected = (variable) => {
  if (currentFieldPath.value === '__yaml__') {
    // YAML 视图：插入到光标位置
    insertVariableToYaml(variable)
  } else {
    // 表单视图：插入到指定字段
    insertVariableToForm(variable)
  }
}

// 插入变量到表单字段
const insertVariableToForm = (variable) => {
  if (!currentFieldPath.value) return

  try {
    console.log('[插入变量] 开始:', { fieldPath: currentFieldPath.value, variable })

    // 创建 formData 的深拷贝以确保响应式更新
    const newFormData = deepClone(formData.value)

    const keys = currentFieldPath.value
    let target = newFormData
    if (target[currentFieldPath.value]){
      target[currentFieldPath.value] = variable
    } else {
      const arrayMatch = keys.match(/^(.+)\[(\d+)\]\.(.+)$/)
      if (arrayMatch) {
        const arrayKey = arrayMatch[1]
        const index = parseInt(arrayMatch[2])
        const value = arrayMatch[3]
        target[arrayKey][index][value] = variable
      } else {
        const envMatch = keys.match(/^config.environments\.(.+)$/)
        if(envMatch){
          const envKey = envMatch[1]
          target['config.environments'][envKey] = variable
        }
      }
    }

    // 更新 formData（触发响应式）
    formData.value = newFormData

    // 强制同步到 YAML（即使在表单视图）
    nextTick(() => {
      handleFormChange(newFormData)
    })

    ElMessage.success('变量已插入')
  } catch (error) {
    console.error('[插入变量] 失败:', error)
    ElMessage.error('插入变量失败: ' + error.message)
  }
}

// 插入变量到 YAML 编辑器
const insertVariableToYaml = (variable) => {
  try {
    // 获取当前 YAML 内容和光标位置（简化实现：追加到末尾或当前行）
    // 注意：完整实现需要 Monaco Editor 的光标 API
    const currentContent = yamlContent.value

    // 简化实现：提示用户手动复制
    navigator.clipboard.writeText(variable)
    ElMessage.success({
      message: `变量 ${variable} 已复制到剪贴板，请在 YAML 中粘贴`,
      duration: 3000
    })
  } catch (error) {
    console.error('插入变量到 YAML 失败:', error)
    ElMessage.error('请手动输入变量: ' + variable)
  }
}

// 确认保存
const handleConfirm = async () => {
  saving.value = true

  try {
    // 如果当前在表单视图，先同步到 YAML
    if (activeTab.value === 'form') {
      handleFormChange(formData.value)
    }

    // 验证表单数据
    const validation = validateFormData(formData.value, TEMPLATE_FIELDS_CONFIG)
    if (!validation.valid) {
      ElMessage.error(validation.errors[0].message)
      activeTab.value = 'form'
      saving.value = false
      return
    }

    // 从当前表单数据构建完整 YAML
    const yamlData = buildYamlFromForm(
      formData.value,
      originalYamlData.value,
      TEMPLATE_FIELDS_CONFIG
    )
    const finalYaml = stringifyYaml(yamlData)

    // 确认保存
    await ElMessageBox.confirm(
      '确定要保存此实验配置吗？',
      '确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'info'
      }
    )

    // 返回完整配置
    emit('confirm', finalYaml)
    emit('update:modelValue', false)
    ElMessage.success('实验配置已保存')
  } catch (error) {
    if (error !== 'cancel') {
      console.error('保存配置失败:', error)
      ElMessage.error('保存失败: ' + error.message)
    }
  } finally {
    saving.value = false
  }
}

// 取消
const handleCancel = () => {
  emit('update:modelValue', false)
}
</script>

<style lang="scss">
// 全局样式（非 scoped）用于对话框容器
.config-editor-dialog-wrapper {
  height: 800px;
  max-height: 90vh;
  margin: 0 !important;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .el-dialog__header {
    flex-shrink: 0;
    padding: 20px;
    margin: 0;
  }

  .el-dialog__body {
    padding: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
  }

  .el-dialog__footer {
    flex-shrink: 0;
    padding: 0;
  }
}
</style>

<style lang="scss" scoped>
.config-editor-dialog {

  .dialog-toolbar {
    padding: 16px 24px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #e4e7ed;
    flex-shrink: 0;
  }

  .config-tabs {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;

    :deep(.el-tabs__header) {
      margin: 0;
      padding: 0 24px;
      background-color: white;
      border-bottom: 1px solid #e4e7ed;
      flex-shrink: 0;
    }

    :deep(.el-tabs__content) {
      flex: 1;
      overflow: hidden;
      min-height: 0;
    }

    :deep(.el-tab-pane) {
      height: 100%;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }

    .tab-label {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .tab-content {
      flex: 1;
      overflow-y: auto;
      overflow-x: hidden;
      min-height: 0;

      &:not(.yaml-view) {
        padding: 20px;
      }

      &.yaml-view {
        padding: 0;
        display: flex;
        flex-direction: column;
        overflow: hidden;

        .yaml-toolbar {
          padding: 16px 24px;
          background-color: #f5f7fa;
          border-bottom: 1px solid #e4e7ed;
          flex-shrink: 0;
        }

        :deep(.yaml-editor-wrapper) {
          flex: 1;
          overflow: hidden;
          min-height: 0;
        }
      }
    }
  }

  .dialog-footer {
    padding: 16px 24px;
    border-top: 1px solid #e4e7ed;
    display: flex;
    justify-content: flex-end;
    gap: 12px;
  }
}
</style>
